#pragma once
#include "publicDefined.h"
#include "operationState.h"
#include <osgViewer/View>
#include <osgGA/GUIEventHandler>
#include <QtCore/qglobal.h>

#ifdef USEREVENTLIBDLL  
#define USEREVENTAPI Q_DECL_EXPORT
#else  
#define USEREVENTAPI Q_DECL_IMPORT
#endif  

/**
 * @brief 是所有客户事件的基类，用于相应用户的gui事件，比如鼠标、按键等消息
 */
class USEREVENTAPI CBaseUserEvent : public osgGA::GUIEventHandler
{
public:
    /**
     * @brief 构造函数
     * @param view 浏览器
     */
    CBaseUserEvent(osgViewer::View* view)
	{
		//禁用裁剪小细节
        osg::CullStack::CullingMode cullingMode = view->getCamera()->getCullingMode();
		cullingMode &= ~(osg::CullStack::SMALL_FEATURE_CULLING);  
        view->getCamera()->setCullingMode(cullingMode);
	}

    /**
     * @brief IsKeyPress 是否按下键
     * @param ea  gui消息，存储按键、鼠标等消息
     */
    virtual bool IsKeyPress(const osgGA::GUIEventAdapter &ea) const;

    /**
     * @brief IsKeyUp 是否松开按键
     * @param ea  gui消息，存储按键、鼠标等消息
     */
    virtual bool IsKeyUp(const osgGA::GUIEventAdapter &ea) const;

    /**
     * @brief IsLeftClick 是否左击
     * @param ea  gui消息，存储按键、鼠标等消息
     */
    virtual bool IsLeftClick(const osgGA::GUIEventAdapter &ea) const;

    /**
     * @brief IsDoubleClick 是否双击
     * @param ea  gui消息，存储按键、鼠标等消息
     */
    virtual bool IsDoubleClick(const osgGA::GUIEventAdapter &ea) const;

    /**
     * @brief IsRightClick 是否右击
     * @param ea  gui消息，存储按键、鼠标等消息
     */
    virtual bool IsRightClick(const osgGA::GUIEventAdapter &ea) const;

    /**
     * @brief IsMouseMove 是否鼠标移动
     * @param ea  gui消息，存储按键、鼠标等消息
     */
    virtual bool IsMouseMove(const osgGA::GUIEventAdapter &ea) const;

    /**
     * @brief PickResult 碰撞检测
     * @param x 浏览器视口上的x坐标
     * @param y 浏览器视口上的y坐标
     * @param mView 浏览器
     */
    virtual const CPickResult PickResult(const float x, const float y, osgViewer::View *mView) const;

    /**
     * @brief ClearGroupResult 清除组结果
     * @param group 需要清理的group
     */
    virtual void ClearGroupResult(osg::ref_ptr<osg::Group> group) const;

    /**
     * @brief CalLength 计算长度
     * @param coord 一组三维点
     */
    virtual double CalLength(const std::vector<osg::Vec3d> coord) const;

    /**
     * @brief CalculateDist 计算距离
     * @param pt1 第一个三维点
     * @param pt2 第二个三维点
     */
    virtual double CalculateDist(const osg::Vec3d pt1, const osg::Vec3d pt2) const;

    /**
     * @brief CalculateArea 计算面积
     * @param coord 一组三维点
     */
    virtual double CalculateArea(std::vector<osg::Vec3d> coord) const;

    /**
     * @brief isActivate 判断事件是否激活
     * @param vecOpState 激活消息，可含有多个事件的激活消息
     * @param ops 事件本身的激活消息
     */
    virtual bool isActivate(const std::vector<OperatingState> vecOpState, const OperatingState ops) const;

    /**
     * @brief updateActivatedStatus 更新事件激活状态，是个纯虚函数，子类需要重写
     * @param vecOpState 激活消息，可含有多个事件的激活消息
     */
    virtual void updateActivatedStatus(const std::vector<OperatingState> vecOpState) = 0;

};
